package com.md.api.service.impl;

import com.md.api.common.utils.RedisUtil;
import com.md.api.common.utils.StringUtils;
import com.md.api.common.utils.TokenUtil;
import com.md.api.dao.*;
import com.md.api.entity.*;
import com.md.api.entity.dto.ComposeQueryDto;
import com.md.api.entity.dto.SkuDetailDto;
import com.md.api.entity.enums.BizType;
import com.md.api.entity.enums.ProductType;
import com.md.api.entity.enums.SaleStatus;
import com.md.api.entity.util.Page;
import com.md.api.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @Author liujie
 * @ClassName ProductServiceImpl
 **/

@Slf4j
@Service
public class ProductServiceImpl implements ProductService {


    @Resource
    PdSkuMapper pdSkuMapper;
    @Resource
    PdSpuMapper pdSpuMapper;
    @Resource
    PdAttributeMapper attributeMapper;
    @Resource
    PdAttributeValueMapper attributeValueMapper;
    @Resource
    PdSpuAttributeRelationMapper spuRelationMapper;
    @Resource
    PdSkuAttributeRelationMapper skuRelationMapper;
    @Resource
    TokenUtil tokenUtil;
    @Resource
    RedisUtil redisUtil;
    @Resource
    ShoppingCartMapper shoppingCartMapper;

    @Override
    public HttpResult page( ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(PdSpu.class);
        List<PdSpu> list = pdSpuMapper.list(qto.getKeyword(),1);
        page.setResult(list);
        return new HttpResult(page);
    }

    @Override
    public HttpResult recommend( ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(PdSpu.class);
        List<PdSpu> list = pdSpuMapper.recommend();
        page.setResult(list);
        return new HttpResult(page);
    }

    @Override
    public HttpResult spuDetail( PdSpu spuo) {

        //产品基本信息和共有属性
        PdSpu spu =  pdSpuMapper.getBaseInfo(spuo.getSpuId());
        List<PdSpuAttributeRelation> publicAttrResult = pdSpuMapper.getPublicAttr(spuo.getSpuId());
        spu.setPublicAttributes(publicAttrResult);

        List<PdAttribute> privateAttrResult = pdSpuMapper.getPrivateAttr(spuo.getSpuId());
        spu.setPrivateAttributes(privateAttrResult);
        return new HttpResult(spu);
    }

    @Override
    public HttpResult skuDetail( HttpServletRequest request,SkuDetailDto dto) {
        String language = request.getHeader("language");
        PdSku sku =  pdSpuMapper.skuDetail(dto.getSpuId(),dto.getAttributeValueIds());
        if (null==sku){
            if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                return HttpResult.fail("The product is sold out");
            }
            return HttpResult.fail("該產品已售罄！");
        }
        return new HttpResult(sku);
    }

    @Override
    public HttpResult attributeList(PdAttribute attribute) {
        List<PdAttribute> pdAttributes = attributeMapper.getByBizType(attribute.getBizType());
        return new HttpResult(pdAttributes);
    }

    @Override
    public HttpResult attributeTree(PdAttribute attribute) {
        List<PdAttribute> pdAttributes = attributeMapper.getByBizType(attribute.getBizType());
        List<Map<String,Object>> resultList = new ArrayList<>();
        for (PdAttribute pdAttribute:pdAttributes){
            Map<String,Object> map = new HashMap<>();
            List<Map<String,Object>> valueList = new ArrayList<>();
            for (PdAttributeValue attributeValue:pdAttribute.getAttributeValueList()){
                Map<String,Object> valueMap = new HashMap<>();
                valueMap.put("label",attributeValue.getAttributeValue());
                valueMap.put("value",attributeValue.getAttributeValueId());
                valueList.add(valueMap);
            }
            map.put("label",pdAttribute.getAttributeName());
            map.put("value",pdAttribute.getAttributeId());
            map.put("children",valueList);
            resultList.add(map);
        }
        return new HttpResult(resultList);
    }

    @Override
    public HttpResult skuUp(PdSku sku) {
        PdSku dbSku = pdSkuMapper.getBySkuId(sku.getSkuId());
        if (ProductType.GOODS.value()==dbSku.getType()) {
            if (null == dbSku.getStockCount()) {
                return HttpResult.fail("庫存量未設置！");
            }
            if (null == dbSku.getLockStockCount()) {
                return HttpResult.fail("最大庫存量未設置！");
            }
            if (null == dbSku.getOrginPrice()) {
                return HttpResult.fail("價格未設置！");
            }
        }
        pdSkuMapper.skuUpOrDown(sku.getSkuId(), SaleStatus.LISTING.value());
        //是否该商品下的所有产品都下架了
        Integer count = pdSpuMapper.listingSku(dbSku.getSpuId());
        PdSpu spu = new PdSpu();
        spu.setSpuId(dbSku.getSpuId());
        if (count>0){
            spu.setSaleStatus(1);
        }else{
            spu.setSaleStatus(-1);
        }
        pdSpuMapper.downOrUp(spu);
        return HttpResult.OK;
    }

    @Override
    public HttpResult skuDown(PdSku sku) {
        pdSkuMapper.skuUpOrDown(sku.getSkuId(), SaleStatus.DELISTING.value());
        //是否该商品下的所有产品都下架了
        PdSku dbSku = pdSkuMapper.getBySkuId(sku.getSkuId());
        Integer count = pdSpuMapper.listingSku(dbSku.getSpuId());
        PdSpu spu = new PdSpu();
        spu.setSpuId(dbSku.getSpuId());
        if (count>0){
            spu.setSaleStatus(1);
        }else{
            spu.setSaleStatus(-1);
        }
        pdSpuMapper.downOrUp(spu);
        return HttpResult.OK;
    }

    @Override
    public HttpResult updateSpuBase(PdSpu spu) {
        pdSpuMapper.updateSpu(spu);
        return HttpResult.OK;
    }

    @Override
    public HttpResult updateBase(PdSku sku) {
        pdSkuMapper.updateBase(sku);
        if (null!=sku.getStockCount()){
            String key = "sku_" + sku.getSkuId();
            redisUtil.set(key, sku.getStockCount());
        }
        return HttpResult.OK;
    }


    @Override
    public HttpResult newAttribute( PdAttribute attribute) {
        String attributeId = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        attribute.setAttributeId(attributeId);
        attributeMapper.insert(attribute);
        return HttpResult.OK;
    }

    @Override
    public HttpResult attributeValueList(String attributeId) {
        List<PdAttributeValue> pdAttributeValue = attributeValueMapper.getByAttributeId(attributeId);
        return new HttpResult(pdAttributeValue);
    }

    @Override
    public HttpResult newAttributeValue(PdAttributeValue attributeValue) {
        PdAttribute attribute = attributeMapper.getByAttributeId(attributeValue.getAttributeId());
        if (BizType.AI_TIMES.value()==attribute.getBizType()&&!attributeValue.getAttributeValue().contains("次")){
            return HttpResult.fail("虛擬產品AI次數屬性明細填寫錯誤，示例：50次");
        }
        if (BizType.FACE_TIMES.value()==attribute.getBizType()&&!attributeValue.getAttributeValue().contains("次")){
            return HttpResult.fail("虛擬產品掃臉取相次數屬性明細填寫錯誤，示例：50次");
        }
        if (BizType.STORAGE.value()==attribute.getBizType()
                &&!attributeValue.getAttributeValue().contains("GB/年")
                &&!attributeValue.getAttributeValue().contains("GB/月")){
            return HttpResult.fail("虛擬產品儲存空間屬性明細填寫錯誤，示例：50GB/年，10GB/月");
        }
        String attributeValueId = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        attributeValue.setAttributeValueId(attributeValueId);
        attributeValueMapper.insert(attributeValue);
        return HttpResult.OK;
    }

    @Override
    public HttpResult deleteAttribute(PdAttribute attribute) {
        Integer count = skuRelationMapper.getCountByAttributeId(attribute.getAttributeId());
        if (count>0){
            return HttpResult.fail("该属性已被使用！");
        }
        attributeMapper.delete(attribute.getAttributeId());
        return HttpResult.OK;
    }

    @Override
    public HttpResult deleteAttributeValue(PdAttributeValue attributeValue) {
        Integer count = skuRelationMapper.getCountByAttributeValueId(attributeValue.getAttributeValueId());
        if (count>0){
            return HttpResult.fail("该属性已被使用！");
        }
        attributeValueMapper.delete(attributeValue.getAttributeValueId());
        return HttpResult.OK;
    }

    @Transactional
    @Override
    public HttpResult newProduct(PdSpu spu) throws Exception  {
        String spuId = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        spu.setSpuId(spuId);
        pdSpuMapper.newSpu(spu);
        //添加共有属性
        if (!CollectionUtils.isEmpty(spu.getPublicAttributes())) {
            List<PdSpuAttributeRelation> publicAttributeList = spu.getPublicAttributes();
            for (PdSpuAttributeRelation attribute : publicAttributeList) {
                attribute.setSpuId(spuId);
                spuRelationMapper.insert(attribute);
            }
        }
        //添加私有属性
        if (!CollectionUtils.isEmpty(spu.getPrivateAttributes())) {
            List<PdAttribute> privateAttributeList = spu.getPrivateAttributes();
            List<List<String>> valueList = new ArrayList<>();
            for (PdAttribute value : privateAttributeList) {
                valueList.add(value.getAttributeValueIds());
            }
            List<String> combine = generateSkuCombine(valueList, 0, "", new ArrayList<>());
            List<PdSku> newSkuList = new ArrayList<>();
            List<PdSkuAttributeRelation> newSkuAttributeRelationList = new ArrayList<>();
            for (String skuAttribute : combine) {
                String skuId = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                List<String> attributeValueIds = StringUtils.toList(skuAttribute);
                for (String attributeValueId : attributeValueIds) {
                    PdSkuAttributeRelation skuAttributeRelation = new PdSkuAttributeRelation();
//                skuAttributeRelation.setAttributeId(attribute.getAttributeId());
                    skuAttributeRelation.setSpuId(spuId);
                    skuAttributeRelation.setSkuId(skuId);
                    skuAttributeRelation.setAttributeValueId(attributeValueId);
                    newSkuAttributeRelationList.add(skuAttributeRelation);
                }
                //初始化sku，后续单独修改每条sku的价格 图片 补充名称
                PdSku sku = new PdSku();
                String attributeValue = attributeValueMapper.getConcatValues(attributeValueIds);
                sku.setType(spu.getType());
                sku.setSpuId(spuId);
                sku.setSkuId(skuId);
                sku.setSkuName(spu.getProductName() + " " + attributeValue);
                sku.setSkuSpecs(attributeValue);
                sku.setSkuDescription(attributeValue);
                newSkuList.add(sku);
            }
            pdSkuMapper.insertBatch(newSkuList);
            skuRelationMapper.insertBatch(newSkuAttributeRelationList);
            //完善attribute_id
            skuRelationMapper.fullAttributeId(spuId);
        }
        return HttpResult.OK;
    }

    public static List<String> generateSkuCombine(List<List<String>> list, int index, String str, List<String> newObjs) {
        if (index == list.size()) {
            newObjs.add(str);
            return newObjs;
        }
        for (String dataStr : list.get(index)) {
            if (StringUtils.isBlank(str)) {
                generateSkuCombine(list, index + 1, str + dataStr, newObjs);
            } else {
                generateSkuCombine(list, index + 1, str + "," + dataStr, newObjs);
            }
        }
        return newObjs;
    }


    @Override
    public HttpResult addShoppingCart(HttpServletRequest request, ShoppingCart shoppingCart) {
        String userId = tokenUtil.getUserId(request);
//        String userId = request.getHeader("userId");
        shoppingCart.setUserId(userId);
        shoppingCartMapper.insert(shoppingCart);
        return HttpResult.OK;
    }
}
